/* Copyright 2010 OddRain
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package com.oddrain.wifieditor.donutpro;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.DialogInterface.OnClickListener;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;

public class WifiConfigList extends Activity implements
        OnSharedPreferenceChangeListener {

    protected static final int SHOW_PREFERENCES = 0;
    private WifiManager wifi;
    private ListView wifiConfigListView;
    private List<WifiConfiguration> wifiConfigList;
    private WifiConfiguration selectedConfig;
    private WifiConfigurationAdapter aa;
    private boolean editingPrefs = false;
    private boolean validAPI = true;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Verify Valid API
        if (Build.VERSION.SDK_INT != Build.VERSION_CODES.DONUT) {
            validAPI = false;
            // Display invalid API Message
            Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("WiFi Config");
            builder.setIcon(android.R.drawable.ic_dialog_alert);
            StringBuilder msg = new StringBuilder();
            msg.append("This version Wi-Fi Config Editor Pro is only supported on Android 1.6");
            msg.append("\n\n");
            msg.append("Please check the Android Market for an updated version of Wi-Fi Config Editor Pro.");
            builder.setMessage(msg.toString());
            builder.setCancelable(false);
            builder.setPositiveButton("Ok", new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    WifiConfigList.this.finish();
                }
            });
            builder.show();
        }

        // Setup WiFi
        wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        wifiConfigListView = (ListView) findViewById(R.id.wifiConfigList);

        wifiConfigListView.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> _av, View _v, int _index,
                    long arg3) {
                if (!validAPI)
                    return;

                selectedConfig = wifiConfigList.get(_index);

                // Populate Preferences
                Context context = getApplicationContext();
                SharedPreferences prefs = PreferenceManager
                        .getDefaultSharedPreferences(context);

                prefs
                        .registerOnSharedPreferenceChangeListener(WifiConfigList.this);
                SharedPreferences.Editor editor = prefs.edit();
                editor.clear();

                if (selectedConfig.SSID != null
                        && selectedConfig.SSID.length() >= 2) {
                    editor.putString(WifiConfigSettings.PREF_SSID,
                            selectedConfig.SSID.substring(1,
                                    selectedConfig.SSID.length() - 1));
                }
                editor.putBoolean(WifiConfigSettings.PREF_HIDDEN_SSID,
                        selectedConfig.hiddenSSID);

                editor.putBoolean(WifiConfigSettings.PREF_KEY_NONE,
                        selectedConfig.allowedKeyManagement
                                .get(WifiConfiguration.KeyMgmt.NONE));
                editor.putBoolean(WifiConfigSettings.PREF_KEY_PSK,
                        selectedConfig.allowedKeyManagement
                                .get(WifiConfiguration.KeyMgmt.WPA_PSK));
                editor.putBoolean(WifiConfigSettings.PREF_KEY_EAP,
                        selectedConfig.allowedKeyManagement
                                .get(WifiConfiguration.KeyMgmt.WPA_EAP));
                editor.putBoolean(WifiConfigSettings.PREF_KEY_IEEE,
                        selectedConfig.allowedKeyManagement
                                .get(WifiConfiguration.KeyMgmt.IEEE8021X));

                editor.putBoolean(WifiConfigSettings.PREF_AUTH_OPEN,
                        selectedConfig.allowedAuthAlgorithms
                                .get(WifiConfiguration.AuthAlgorithm.OPEN));
                editor.putBoolean(WifiConfigSettings.PREF_AUTH_LEAP,
                        selectedConfig.allowedAuthAlgorithms
                                .get(WifiConfiguration.AuthAlgorithm.LEAP));
                editor.putBoolean(WifiConfigSettings.PREF_AUTH_SHARED,
                        selectedConfig.allowedAuthAlgorithms
                                .get(WifiConfiguration.AuthAlgorithm.SHARED));

                editor.putBoolean(WifiConfigSettings.PREF_SEC_WPA,
                        selectedConfig.allowedProtocols
                                .get(WifiConfiguration.Protocol.WPA));
                editor.putBoolean(WifiConfigSettings.PREF_SEC_RSN,
                        selectedConfig.allowedProtocols
                                .get(WifiConfiguration.Protocol.RSN));

                editor.putBoolean(WifiConfigSettings.PREF_PAIR_NONE,
                        selectedConfig.allowedPairwiseCiphers
                                .get(WifiConfiguration.PairwiseCipher.NONE));
                editor.putBoolean(WifiConfigSettings.PREF_PAIR_CCMP,
                        selectedConfig.allowedPairwiseCiphers
                                .get(WifiConfiguration.PairwiseCipher.CCMP));
                editor.putBoolean(WifiConfigSettings.PREF_PAIR_TKIP,
                        selectedConfig.allowedPairwiseCiphers
                                .get(WifiConfiguration.PairwiseCipher.TKIP));

                editor.putBoolean(WifiConfigSettings.PREF_GRP_WEP40,
                        selectedConfig.allowedGroupCiphers
                                .get(WifiConfiguration.GroupCipher.WEP40));
                editor.putBoolean(WifiConfigSettings.PREF_GRP_WEP104,
                        selectedConfig.allowedGroupCiphers
                                .get(WifiConfiguration.GroupCipher.WEP104));
                editor.putBoolean(WifiConfigSettings.PREF_GRP_TKIP,
                        selectedConfig.allowedGroupCiphers
                                .get(WifiConfiguration.GroupCipher.TKIP));
                editor.putBoolean(WifiConfigSettings.PREF_GRP_CCMP,
                        selectedConfig.allowedGroupCiphers
                                .get(WifiConfiguration.GroupCipher.CCMP));

                if (selectedConfig.wepKeys[0] != null
                        && selectedConfig.wepKeys[0].length() >= 2) {
                    editor.putString(WifiConfigSettings.PREF_WEPKEY_KEY0,
                            selectedConfig.wepKeys[0].substring(1,
                                    selectedConfig.wepKeys[0].length() - 1));
                }

                if (selectedConfig.wepKeys[1] != null
                        && selectedConfig.wepKeys[1].length() >= 2) {
                    editor.putString(WifiConfigSettings.PREF_WEPKEY_KEY1,
                            selectedConfig.wepKeys[1].substring(1,
                                    selectedConfig.wepKeys[1].length() - 1));
                }

                if (selectedConfig.wepKeys[2] != null
                        && selectedConfig.wepKeys[2].length() >= 2) {
                    editor.putString(WifiConfigSettings.PREF_WEPKEY_KEY2,
                            selectedConfig.wepKeys[2].substring(1,
                                    selectedConfig.wepKeys[2].length() - 1));
                }

                if (selectedConfig.wepKeys[3] != null
                        && selectedConfig.wepKeys[3].length() >= 2) {
                    editor.putString(WifiConfigSettings.PREF_WEPKEY_KEY3,
                            selectedConfig.wepKeys[3].substring(1,
                                    selectedConfig.wepKeys[3].length() - 1));
                }

                if (selectedConfig.preSharedKey != null
                        && selectedConfig.preSharedKey.length() >= 2) {
                    editor.putString(WifiConfigSettings.PREF_WPA_KEY,
                            selectedConfig.preSharedKey.substring(1,
                                    selectedConfig.preSharedKey.length() - 1));
                }

                if (selectedConfig.eap != null) {
                    editor.putString(WifiConfigSettings.PREF_ENTR_EAP,
                            selectedConfig.eap);
                }

                if (selectedConfig.phase2 != null) {
                    editor.putString(WifiConfigSettings.PREF_ENTR_PHASE2,
                            selectedConfig.phase2);
                }

                if (selectedConfig.identity != null
                        && selectedConfig.identity.length() >= 2) {
                    editor.putString(WifiConfigSettings.PREF_ENTR_IDENT,
                            selectedConfig.identity.substring(1,
                                    selectedConfig.identity.length() - 1));
                }

                if (selectedConfig.anonymousIdentity != null
                        && selectedConfig.anonymousIdentity.length() >= 2) {
                    editor.putString(WifiConfigSettings.PREF_ENTR_ANON_IDENT,
                            selectedConfig.anonymousIdentity
                                    .substring(1,
                                            selectedConfig.anonymousIdentity
                                                    .length() - 1));
                }

                if (selectedConfig.password != null
                        && selectedConfig.password.length() >= 2) {
                    editor.putString(WifiConfigSettings.PREF_ENTR_PASS,
                            selectedConfig.password.substring(1,
                                    selectedConfig.password.length() - 1));
                }

                if (selectedConfig.clientCert != null
                        && selectedConfig.clientCert.length() >= 2) {
                    editor.putString(WifiConfigSettings.PREF_ENTR_CLIENT_CERT,
                            selectedConfig.clientCert.substring(1,
                                    selectedConfig.clientCert.length() - 1));
                }

                if (selectedConfig.caCert != null
                        && selectedConfig.caCert.length() >= 2) {
                    editor.putString(WifiConfigSettings.PREF_ENTR_CA_CERT,
                            selectedConfig.caCert.substring(1,
                                    selectedConfig.caCert.length() - 1));
                }

                if (selectedConfig.privateKey != null
                        && selectedConfig.privateKey.length() >= 2) {
                    editor.putString(WifiConfigSettings.PREF_ENTR_PRIV_KEY,
                            selectedConfig.privateKey.substring(1,
                                    selectedConfig.privateKey.length() - 1));
                }

                if (selectedConfig.privateKeyPasswd != null
                        && selectedConfig.privateKeyPasswd.length() >= 2) {
                    editor.putString(
                            WifiConfigSettings.PREF_ENTR_PRIV_KEY_PASS,
                            selectedConfig.privateKeyPasswd
                                    .substring(1,
                                            selectedConfig.privateKeyPasswd
                                                    .length() - 1));
                }

                editor.commit();
                editingPrefs = true;

                // Display Preferences
                Intent i = new Intent(context, WifiConfigSettings.class);
                i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
                startActivityForResult(i, SHOW_PREFERENCES);

            }
        });

        wifiConfigList = new ArrayList<WifiConfiguration>();
        int resID = R.layout.wificonfiguration_item;
        aa = new WifiConfigurationAdapter(this, resID, wifiConfigList);
        wifiConfigListView.setAdapter(aa);

        Context context = getApplicationContext();
        context.registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                loadWifiConfigs();
                System.out.println("Recieved wifi state changed action:"
                        + intent);
            }
        }, new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));

        checkWifiState();
    }

    private void loadWifiConfigs() {
        wifiConfigList.clear();
        List<WifiConfiguration> configs = wifi.getConfiguredNetworks();
        for (WifiConfiguration config : configs) {
            wifiConfigList.add(config);
        }
        aa.notifyDataSetChanged();
    }

    private void checkWifiState() {
        boolean enabled = wifi.isWifiEnabled();
        if (!enabled && validAPI) {
            Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("WiFi Config");
            builder.setIcon(android.R.drawable.ic_dialog_alert);
            builder
                    .setMessage("Wi-Fi is currently disabled. Do you want to enable it now?");
            builder.setPositiveButton("Yes", new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    wifi.setWifiEnabled(true);
                }
            });
            builder.setNegativeButton("No", null);
            builder.show();
        } else {
            loadWifiConfigs();
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        checkWifiState();
        editingPrefs = false;
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
            String key) {
        if (editingPrefs) {
            // Save
            saveWiFiConfig();
        }
    }

    private void saveWiFiConfig() {
        if (!validAPI)
            return;

        // Save Wifi Config from Preferences
        Context context = getApplicationContext();
        SharedPreferences prefs = PreferenceManager
                .getDefaultSharedPreferences(context);

        if (prefs.getString(WifiConfigSettings.PREF_SSID, null) != null) {
            selectedConfig.SSID = "\""
                    + prefs.getString(WifiConfigSettings.PREF_SSID, "") + "\"";
        }

        if (prefs.getBoolean(WifiConfigSettings.PREF_HIDDEN_SSID, false)) {
            selectedConfig.hiddenSSID = true;
        }

        selectedConfig.allowedKeyManagement.clear();
        if (prefs.getBoolean(WifiConfigSettings.PREF_KEY_IEEE, false)) {
            selectedConfig.allowedKeyManagement
                    .set(WifiConfiguration.KeyMgmt.IEEE8021X);
        }
        if (prefs.getBoolean(WifiConfigSettings.PREF_KEY_PSK, false)) {
            selectedConfig.allowedKeyManagement
                    .set(WifiConfiguration.KeyMgmt.WPA_PSK);
        }
        if (prefs.getBoolean(WifiConfigSettings.PREF_KEY_EAP, false)) {
            selectedConfig.allowedKeyManagement
                    .set(WifiConfiguration.KeyMgmt.WPA_EAP);
        }
        if (prefs.getBoolean(WifiConfigSettings.PREF_KEY_NONE, false)) {
            selectedConfig.allowedKeyManagement
                    .set(WifiConfiguration.KeyMgmt.NONE);
        }

        // GroupCiphers
        selectedConfig.allowedGroupCiphers.clear();
        if (prefs.getBoolean(WifiConfigSettings.PREF_GRP_WEP40, false)) {
            selectedConfig.allowedGroupCiphers
                    .set(WifiConfiguration.GroupCipher.WEP40);
        }
        if (prefs.getBoolean(WifiConfigSettings.PREF_GRP_WEP104, false)) {
            selectedConfig.allowedGroupCiphers
                    .set(WifiConfiguration.GroupCipher.WEP104);
        }
        if (prefs.getBoolean(WifiConfigSettings.PREF_GRP_CCMP, false)) {
            selectedConfig.allowedGroupCiphers
                    .set(WifiConfiguration.GroupCipher.CCMP);
        }
        if (prefs.getBoolean(WifiConfigSettings.PREF_GRP_TKIP, false)) {
            selectedConfig.allowedGroupCiphers
                    .set(WifiConfiguration.GroupCipher.TKIP);
        }

        // PairwiseCiphers
        selectedConfig.allowedPairwiseCiphers.clear();
        if (prefs.getBoolean(WifiConfigSettings.PREF_PAIR_TKIP, false)) {
            selectedConfig.allowedPairwiseCiphers
                    .set(WifiConfiguration.PairwiseCipher.TKIP);
        }
        if (prefs.getBoolean(WifiConfigSettings.PREF_PAIR_CCMP, false)) {
            selectedConfig.allowedPairwiseCiphers
                    .set(WifiConfiguration.PairwiseCipher.CCMP);
        }
        if (prefs.getBoolean(WifiConfigSettings.PREF_PAIR_NONE, false)) {
            selectedConfig.allowedPairwiseCiphers
                    .set(WifiConfiguration.PairwiseCipher.NONE);
        }

        // Authentication Algorithms
        selectedConfig.allowedAuthAlgorithms.clear();
        if (prefs.getBoolean(WifiConfigSettings.PREF_AUTH_OPEN, false)) {
            selectedConfig.allowedAuthAlgorithms
                    .set(WifiConfiguration.AuthAlgorithm.OPEN);
        }
        if (prefs.getBoolean(WifiConfigSettings.PREF_AUTH_SHARED, false)) {
            selectedConfig.allowedAuthAlgorithms
                    .set(WifiConfiguration.AuthAlgorithm.SHARED);
        }
        if (prefs.getBoolean(WifiConfigSettings.PREF_AUTH_LEAP, false)) {
            selectedConfig.allowedAuthAlgorithms
                    .set(WifiConfiguration.AuthAlgorithm.LEAP);
        }

        // Protocols
        selectedConfig.allowedProtocols.clear();
        if (prefs.getBoolean(WifiConfigSettings.PREF_SEC_RSN, false)) {
            selectedConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
        }
        if (prefs.getBoolean(WifiConfigSettings.PREF_SEC_WPA, false)) {
            selectedConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
        }

        // WEP Keys
        if (prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY0, null) != null) {
            selectedConfig.wepKeys[0] = "\""
                    + prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY0, "")
                    + "\"";
        }
        if (prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY1, null) != null) {
            selectedConfig.wepKeys[1] = "\""
                    + prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY1, "")
                    + "\"";
        }
        if (prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY2, null) != null) {
            selectedConfig.wepKeys[2] = "\""
                    + prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY2, "")
                    + "\"";
        }
        if (prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY3, null) != null) {
            selectedConfig.wepKeys[3] = "\""
                    + prefs.getString(WifiConfigSettings.PREF_WEPKEY_KEY3, "")
                    + "\"";
        }

        if (prefs.getString(WifiConfigSettings.PREF_WPA_KEY, null) != null) {
            selectedConfig.preSharedKey = "\""
                    + prefs.getString(WifiConfigSettings.PREF_WPA_KEY, "")
                    + "\"";
        }

        // Enterprise Settings
        if (prefs.getString(WifiConfigSettings.PREF_ENTR_EAP, null) != null) {
            selectedConfig.eap = prefs.getString(
                    WifiConfigSettings.PREF_ENTR_EAP, "");
        }

        if (prefs.getString(WifiConfigSettings.PREF_ENTR_PHASE2, null) != null) {
            selectedConfig.phase2 = prefs.getString(
                    WifiConfigSettings.PREF_ENTR_PHASE2, "");
        }

        if (prefs.getString(WifiConfigSettings.PREF_ENTR_IDENT, null) != null) {
            selectedConfig.identity = "\""
                    + prefs.getString(WifiConfigSettings.PREF_ENTR_IDENT, "")
                    + "\"";
        }

        if (prefs.getString(WifiConfigSettings.PREF_ENTR_ANON_IDENT, null) != null) {
            selectedConfig.anonymousIdentity = "\""
                    + prefs.getString(WifiConfigSettings.PREF_ENTR_ANON_IDENT,
                            "") + "\"";
        }

        if (prefs.getString(WifiConfigSettings.PREF_ENTR_PASS, null) != null) {
            selectedConfig.password = "\""
                    + prefs.getString(WifiConfigSettings.PREF_ENTR_PASS, "")
                    + "\"";
        }

        if (prefs.getString(WifiConfigSettings.PREF_ENTR_CLIENT_CERT, null) != null) {
            selectedConfig.clientCert = "\""
                    + prefs.getString(WifiConfigSettings.PREF_ENTR_CLIENT_CERT,
                            "") + "\"";
        }

        if (prefs.getString(WifiConfigSettings.PREF_ENTR_CA_CERT, null) != null) {
            selectedConfig.caCert = "\""
                    + prefs.getString(WifiConfigSettings.PREF_ENTR_CA_CERT, "")
                    + "\"";
        }

        if (prefs.getString(WifiConfigSettings.PREF_ENTR_PRIV_KEY, null) != null) {
            selectedConfig.privateKey = "\""
                    + prefs
                            .getString(WifiConfigSettings.PREF_ENTR_PRIV_KEY,
                                    "") + "\"";
        }

        if (prefs.getString(WifiConfigSettings.PREF_ENTR_PRIV_KEY_PASS, null) != null) {
            selectedConfig.privateKeyPasswd = "\""
                    + prefs.getString(
                            WifiConfigSettings.PREF_ENTR_PRIV_KEY_PASS, "")
                    + "\"";
        }

        wifi.updateNetwork(selectedConfig);
        wifi.enableNetwork(selectedConfig.networkId, false);
        wifi.saveConfiguration();
    }
}